void
gtk_container_snapshot_child (GtkContainer *container,
- GskRenderNode *container_node,
GtkWidget *child,
- const GtkSnapshot *snapshot)
+ GtkSnapshot *snapshot)
{
- GtkSnapshot child_snapshot;
- GskRenderNode *child_node;
int x, y;
g_return_if_fail (GTK_IS_CONTAINER (container));
g_return_if_fail (GTK_IS_WIDGET (child));
g_return_if_fail (_gtk_widget_get_parent (child) == GTK_WIDGET (container));
- g_return_if_fail (GSK_IS_RENDER_NODE (container_node));
g_return_if_fail (snapshot != NULL);
gtk_container_get_translation_to_child (container, child, &x, &y);
- gtk_snapshot_init_translate (&child_snapshot, snapshot, x, y);
- child_node = gtk_widget_snapshot (child, &child_snapshot);
-
- if (child_node)
- {
- gsk_render_node_append_child (container_node, child_node);
- gsk_render_node_unref (child_node);
- }
-
- gtk_snapshot_finish (&child_snapshot);
+ gtk_snapshot_translate_2d (snapshot, x, y);
+ gtk_widget_snapshot (child, snapshot);
+ gtk_snapshot_translate_2d (snapshot, -x, -y);
}
/**
GtkWidget *child,
GskRenderer *renderer,
GskRenderNode *parent_node);
-void gtk_container_snapshot_child (GtkContainer *container,
- GskRenderNode *container_node,
- GtkWidget *child,
- const GtkSnapshot *snapshot);
+void gtk_container_snapshot_child (GtkContainer *container,
+ GtkWidget *child,
+ GtkSnapshot *snapshot);
G_END_DECLS
}
}
-GskRenderNode *
-gtk_debug_updates_snapshot (GtkWidget *widget,
- const GtkSnapshot *snapshot)
+void
+gtk_debug_updates_snapshot (GtkWidget *widget,
+ GtkSnapshot *snapshot)
{
GQueue *updates;
- GskRenderNode *node;
GtkDebugUpdate *draw;
GdkRectangle rect;
gint64 timestamp;
GList *l;
if (!gtk_debug_updates_get_enabled_for_display (gtk_widget_get_display (widget)))
- return NULL;
+ return;
updates = g_object_get_qdata (G_OBJECT (widget), _gtk_debug_updates_quark);
if (updates == NULL)
- return NULL;
+ return;
timestamp = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
gtk_debug_updates_print (updates, NULL, "Painting at %lli", (long long) timestamp);
- node = gtk_snapshot_create_render_node (snapshot, "Debug Updates");
gtk_debug_updates_queue_get_extents (updates, &rect);
- gsk_render_node_set_bounds (node, &(graphene_rect_t) GRAPHENE_RECT_INIT(rect.x, rect.y, rect.width, rect.height));
-
- cr = gsk_render_node_get_draw_context (node, gtk_snapshot_get_renderer (snapshot));
+ cr = gtk_snapshot_append_cairo_node (snapshot,
+ &(graphene_rect_t) GRAPHENE_RECT_INIT(rect.x, rect.y, rect.width, rect.height),
+ "Debug Updates");
for (l = g_queue_peek_head_link (updates); l != NULL; l = l->next)
{
}
cairo_destroy (cr);
-
- return node;
}
void gtk_debug_updates_add (GtkWidget *widget,
const cairo_region_t *region);
-GskRenderNode * gtk_debug_updates_snapshot (GtkWidget *widget,
- const GtkSnapshot *snapshot);
+void gtk_debug_updates_snapshot (GtkWidget *widget,
+ GtkSnapshot *snapshot);
G_END_DECLS
#include "gtksnapshot.h"
#include "gtksnapshotprivate.h"
+#include "gsk/gskrendernodeprivate.h"
+
void
-gtk_snapshot_init (GtkSnapshot *state,
- const GtkSnapshot *parent,
- const graphene_matrix_t *transform)
+gtk_snapshot_init (GtkSnapshot *state,
+ GskRenderer *renderer)
{
- state->parent = parent;
- state->renderer = parent->renderer;
-
- graphene_matrix_init_from_matrix (&state->transform, transform);
+ state->node = NULL;
+ state->root = NULL;
+ state->renderer = renderer;
+
+ graphene_matrix_init_identity (&state->transform);
}
-void
-gtk_snapshot_init_translate (GtkSnapshot *state,
- const GtkSnapshot *parent,
- int x,
- int y)
+GskRenderNode *
+gtk_snapshot_finish (GtkSnapshot *state)
{
- graphene_matrix_t matrix;
-
- graphene_matrix_init_translate (&matrix, &(graphene_point3d_t) GRAPHENE_POINT3D_INIT (x, y, 0));
+ if (state->node != NULL)
+ {
+ g_warning ("Too many gtk_snapshot_push() calls.");
+ }
- gtk_snapshot_init (state, parent, &matrix);
+ return state->root;
}
void
-gtk_snapshot_init_root (GtkSnapshot *state,
- GskRenderer *renderer)
+gtk_snapshot_push (GtkSnapshot *state,
+ GskRenderNode *node)
{
- state->parent = NULL;
- state->renderer = renderer;
+ gtk_snapshot_append_node (state, node);
+ state->node = node;
graphene_matrix_init_identity (&state->transform);
}
void
-gtk_snapshot_finish (GtkSnapshot *state)
+gtk_snapshot_pop (GtkSnapshot *state)
{
- /* nothing to do so far */
+ if (state->node == NULL)
+ {
+ g_warning ("Too many gtk_snapshot_pop() calls.");
+ return;
+ }
+
+ gsk_render_node_get_transform (state->node, &state->transform);
+
+ state->node = gsk_render_node_get_parent (state->node);
}
GskRenderer *
return state->renderer;
}
+#if 0
GskRenderNode *
gtk_snapshot_create_render_node (const GtkSnapshot *state,
const char *name,
return node;
}
+#endif
+
+void
+gtk_snapshot_set_transform (GtkSnapshot *state,
+ const graphene_matrix_t *transform)
+{
+ graphene_matrix_init_from_matrix (&state->transform, transform);
+}
+
+void
+gtk_snapshot_transform (GtkSnapshot *state,
+ const graphene_matrix_t *transform)
+{
+ graphene_matrix_t result;
+
+ graphene_matrix_multiply (&state->transform, transform, &result);
+ graphene_matrix_init_from_matrix (&state->transform, &result);
+}
+
+void
+gtk_snapshot_translate_2d (GtkSnapshot *state,
+ int x,
+ int y)
+{
+ graphene_matrix_t transform;
+ graphene_point3d_t point;
+
+ graphene_point3d_init (&point, x, y, 0);
+ graphene_matrix_init_translate (&transform, &point);
+ gtk_snapshot_transform (state, &transform);
+}
+
+void
+gtk_snapshot_append_node (GtkSnapshot *state,
+ GskRenderNode *node)
+{
+ g_return_if_fail (state != NULL);
+ g_return_if_fail (GSK_IS_RENDER_NODE (node));
+
+ gsk_render_node_set_transform (node, &state->transform);
+ if (state->node)
+ gsk_render_node_append_child (state->node, node);
+ else if (state->root == NULL)
+ state->root = gsk_render_node_ref (node);
+ else
+ {
+ g_warning ("Tried appending a node to an already finished snapshot.");
+ }
+}
+
+cairo_t *
+gtk_snapshot_append_cairo_node (GtkSnapshot *state,
+ const graphene_rect_t *bounds,
+ const char *name,
+ ...)
+{
+ GskRenderNode *node;
+
+ g_return_val_if_fail (state != NULL, NULL);
+ g_return_val_if_fail (bounds != NULL, NULL);
+
+ node = gsk_renderer_create_render_node (state->renderer);
+ gsk_render_node_set_bounds (node, bounds);
+
+ if (name)
+ {
+ va_list args;
+ char *str;
+
+ va_start (args, name);
+ str = g_strdup_vprintf (name, args);
+ va_end (args);
+
+ gsk_render_node_set_name (node, str);
+
+ g_free (str);
+ }
+
+ gtk_snapshot_append_node (state, node);
+ gsk_render_node_unref (node);
+
+ return gsk_render_node_get_draw_context (node, state->renderer);
+}
+
+cairo_t *
+gtk_snapshot_push_cairo_node (GtkSnapshot *state,
+ const graphene_rect_t *bounds,
+ const char *name,
+ ...)
+{
+ GskRenderNode *node;
+
+ g_return_val_if_fail (state != NULL, NULL);
+ g_return_val_if_fail (bounds != NULL, NULL);
+
+ node = gsk_renderer_create_render_node (state->renderer);
+ gsk_render_node_set_bounds (node, bounds);
+
+ if (name)
+ {
+ va_list args;
+ char *str;
+
+ va_start (args, name);
+ str = g_strdup_vprintf (name, args);
+ va_end (args);
+
+ gsk_render_node_set_name (node, str);
+
+ g_free (str);
+ }
+
+ gtk_snapshot_push (state, node);
+ gsk_render_node_unref (node);
+
+ return gsk_render_node_get_draw_context (node, state->renderer);
+}
GDK_AVAILABLE_IN_3_90
-GskRenderer * gtk_snapshot_get_renderer (const GtkSnapshot *state);
+GskRenderer * gtk_snapshot_get_renderer (const GtkSnapshot *state);
GDK_AVAILABLE_IN_3_90
-GskRenderNode * gtk_snapshot_create_render_node (const GtkSnapshot *state,
- const char *name,
- ...) G_GNUC_PRINTF(2, 3);
+void gtk_snapshot_push (GtkSnapshot *state,
+ GskRenderNode *node);
+GDK_AVAILABLE_IN_3_90
+cairo_t * gtk_snapshot_push_cairo_node (GtkSnapshot *state,
+ const graphene_rect_t *bounds,
+ const char *name,
+ ...) G_GNUC_PRINTF(3, 4);
+GDK_AVAILABLE_IN_3_90
+void gtk_snapshot_pop (GtkSnapshot *state);
+
+GDK_AVAILABLE_IN_3_90
+void gtk_snapshot_set_transform (GtkSnapshot *state,
+ const graphene_matrix_t *transform);
+GDK_AVAILABLE_IN_3_90
+void gtk_snapshot_transform (GtkSnapshot *state,
+ const graphene_matrix_t *matrix);
+GDK_AVAILABLE_IN_3_90
+void gtk_snapshot_translate_2d (GtkSnapshot *state,
+ int x,
+ int y);
+
+GDK_AVAILABLE_IN_3_90
+void gtk_snapshot_append_node (GtkSnapshot *state,
+ GskRenderNode *node);
+GDK_AVAILABLE_IN_3_90
+cairo_t * gtk_snapshot_append_cairo_node (GtkSnapshot *state,
+ const graphene_rect_t *bounds,
+ const char *name,
+ ...) G_GNUC_PRINTF(3, 4);
G_END_DECLS
G_BEGIN_DECLS
struct _GtkSnapshot {
- const GtkSnapshot *parent;
+ GskRenderNode *node;
+ GskRenderNode *root;
GskRenderer *renderer;
};
void gtk_snapshot_init (GtkSnapshot *state,
- const GtkSnapshot *parent,
- const graphene_matrix_t *transform);
-void gtk_snapshot_init_translate (GtkSnapshot *state,
- const GtkSnapshot *parent,
- int x,
- int y);
-void gtk_snapshot_init_root (GtkSnapshot *state,
GskRenderer *renderer);
+GskRenderNode * gtk_snapshot_finish (GtkSnapshot *state);
static inline const graphene_matrix_t *
gtk_snapshot_get_transform (const GtkSnapshot *snapshot)
return &snapshot->transform;
}
-void gtk_snapshot_finish (GtkSnapshot *state);
-
G_END_DECLS
#endif /* __GTK_SNAPSHOT_PRIVATE_H__ */
widget->priv->clip.width,
widget->priv->clip.height);
fallback = gsk_renderer_create_fallback (renderer, &viewport, cr);
- gtk_snapshot_init_root (&snapshot, renderer);
- node = gtk_widget_snapshot (widget, &snapshot);
+ gtk_snapshot_init (&snapshot, renderer);
+ gtk_widget_snapshot (widget, &snapshot);
+ node = gtk_snapshot_finish (&snapshot);
if (node != NULL)
{
gsk_renderer_render (fallback, node, NULL);
gsk_render_node_unref (node);
}
- gtk_snapshot_finish (&snapshot);
g_object_unref (fallback);
}
GtkSnapshot snapshot;
GskRenderNode *node;
- gtk_snapshot_init_root (&snapshot, renderer);
+ gtk_snapshot_init (&snapshot, renderer);
- node = gtk_widget_snapshot (widget, &snapshot);
+ gtk_widget_snapshot (widget, &snapshot);
- gtk_snapshot_finish (&snapshot);
+ node = gtk_snapshot_finish (&snapshot);
return node;
}
-GskRenderNode *
-gtk_widget_snapshot (GtkWidget *widget,
- const GtkSnapshot *snapshot)
+void
+gtk_widget_snapshot (GtkWidget *widget,
+ GtkSnapshot *snapshot)
{
GtkWidgetClass *klass = GTK_WIDGET_GET_CLASS (widget);
- GskRenderNode *node;
- graphene_matrix_t m;
- graphene_point3d_t p;
graphene_rect_t bounds;
GtkAllocation clip;
GtkAllocation alloc;
if (_gtk_widget_get_alloc_needed (widget))
- return NULL;
+ return;
gtk_widget_get_clip (widget, &clip);
_gtk_widget_get_allocation (widget, &alloc);
- graphene_rect_init (&bounds, 0, 0, clip.width, clip.height);
- graphene_matrix_init_translate (&m, graphene_point3d_init (&p, clip.x, clip.y, 0.f));
+ graphene_rect_init (&bounds, alloc.x - clip.x, alloc.y - clip.y, clip.width, clip.height);
/* Compatibility mode: if the widget does not have a render node, we draw
* using gtk_widget_draw() on a temporary node
if (klass->get_render_node == NULL &&
klass->snapshot == NULL)
{
- GskRenderNode *tmp;
cairo_t *cr;
- tmp = gtk_snapshot_create_render_node (snapshot, "Fallback<%s>", G_OBJECT_TYPE_NAME (widget));
- gsk_render_node_set_bounds (tmp, &bounds);
- gsk_render_node_set_transform (tmp, &m);
-
- cr = gsk_render_node_get_draw_context (tmp, gtk_snapshot_get_renderer (snapshot));
- cairo_translate (cr, alloc.x - clip.x, alloc.y - clip.y);
+ cr = gtk_snapshot_append_cairo_node (snapshot,
+ &bounds, "Fallback<%s>",
+ G_OBJECT_TYPE_NAME (widget));
gtk_widget_draw_internal (widget, cr, TRUE);
cairo_destroy (cr);
-
- node = tmp;
}
else
{
+ if (g_signal_has_handler_pending (widget, widget_signals[DRAW], 0, FALSE))
+ gtk_snapshot_push (snapshot, &bounds, "DrawSignal<%s>", G_OBJECT_TYPE_NAME (widget));
+
if (klass->snapshot)
- node = klass->snapshot (widget, snapshot);
+ klass->snapshot (widget, snapshot);
else
- node = klass->get_render_node (widget, gtk_snapshot_get_renderer (snapshot));
+ {
+ GskRenderNode *node;
+
+ node = klass->get_render_node (widget, gtk_snapshot_get_renderer (snapshot));
+ if (node)
+ {
+ gtk_snapshot_append_node (snapshot, node);
+ gsk_render_node_unref (node);
+ }
+ }
/* Compatibility mode: if there's a ::draw signal handler, we add a
* child node with the contents of the handler
*/
if (g_signal_has_handler_pending (widget, widget_signals[DRAW], 0, FALSE))
{
- GskRenderNode *tmp;
gboolean result;
cairo_t *cr;
- tmp = gtk_snapshot_create_render_node (snapshot, "DrawSignal<%s>", G_OBJECT_TYPE_NAME (widget));
- gsk_render_node_set_bounds (tmp, &bounds);
-
- cr = gsk_render_node_get_draw_context (tmp, gtk_snapshot_get_renderer (snapshot));
- cairo_translate (cr, alloc.x - clip.x, alloc.y - clip.y);
+ cr = gtk_snapshot_append_cairo_node (snapshot,
+ &bounds,
+ "DrawSignalContents<%s>", G_OBJECT_TYPE_NAME (widget));
g_signal_emit (widget, widget_signals[DRAW], 0, cr, &result);
cairo_destroy (cr);
-
- if (node != NULL)
- {
- gsk_render_node_append_child (node, tmp);
- gsk_render_node_unref (tmp);
- }
- else
- {
- node = tmp;
- }
+ gtk_snapshot_pop (snapshot);
}
}
-
- if (node)
- gsk_render_node_set_transform (node, gtk_snapshot_get_transform (snapshot));
-
- return node;
}
void
if (renderer == NULL)
return;
- gtk_snapshot_init_root (&snapshot, renderer);
- root = gtk_widget_snapshot (widget, &snapshot);
- gtk_snapshot_finish (&snapshot);
+ gtk_snapshot_init (&snapshot, renderer);
+ gtk_widget_snapshot (widget, &snapshot);
+ root = gtk_snapshot_finish (&snapshot);
if (root == NULL)
return;
GskRenderNode *(* get_render_node) (GtkWidget *widget,
GskRenderer *renderer);
- GskRenderNode *(* snapshot) (GtkWidget *widget,
- const GtkSnapshot *snapshot);
+ void (* snapshot) (GtkWidget *widget,
+ GtkSnapshot *snapshot);
/*< private >*/
GskRenderNode * gtk_widget_get_render_node (GtkWidget *widget,
GskRenderer *renderer);
-GskRenderNode * gtk_widget_snapshot (GtkWidget *widget,
- const GtkSnapshot *snapshot);
+void gtk_widget_snapshot (GtkWidget *widget,
+ GtkSnapshot *snapshot);
GskRenderNode * gtk_widget_create_render_node (GtkWidget *widget,
GskRenderer *renderer,
static void gtk_window_keys_changed (GtkWindow *window);
static gboolean gtk_window_enable_debugging (GtkWindow *window,
gboolean toggle);
-static GskRenderNode *gtk_window_snapshot (GtkWidget *widget,
- const GtkSnapshot *snapshot);
+static void gtk_window_snapshot (GtkWidget *widget,
+ GtkSnapshot *snapshot);
static void gtk_window_unset_transient_for (GtkWindow *window);
static void gtk_window_transient_parent_realized (GtkWidget *parent,
GtkWidget *window);
* Redrawing functions *
***********************/
-static GskRenderNode *
-gtk_window_snapshot (GtkWidget *widget,
- const GtkSnapshot *snapshot)
+static void
+gtk_window_snapshot (GtkWidget *widget,
+ GtkSnapshot *snapshot)
{
GtkWindowPrivate *priv = GTK_WINDOW (widget)->priv;
GtkStyleContext *context;
- GskRenderNode *node, *updates_node;
GtkAllocation allocation;
GtkBorder window_border;
gint title_height;
graphene_rect_init (&bounds, allocation.x, allocation.y, allocation.width, allocation.height);
graphene_matrix_init_translate (&m, graphene_point3d_init (&p, allocation.x, allocation.y, 0.));
- node = gtk_snapshot_create_render_node (snapshot, "Window Decoration");
- gsk_render_node_set_bounds (node, &bounds);
- gsk_render_node_set_transform (node, &m);
-
- cr = gsk_render_node_get_draw_context (node, gtk_snapshot_get_renderer (snapshot));
+ cr = gtk_snapshot_push_cairo_node (snapshot,
+ &bounds,
+ "Window Decoration");
if (priv->client_decorated &&
priv->decorated &&
cairo_destroy (cr);
if (priv->title_box != NULL)
- gtk_container_snapshot_child (GTK_CONTAINER (widget), node, priv->title_box, snapshot);
+ gtk_container_snapshot_child (GTK_CONTAINER (widget), priv->title_box, snapshot);
if (gtk_bin_get_child (GTK_BIN (widget)))
- gtk_container_snapshot_child (GTK_CONTAINER (widget), node, gtk_bin_get_child (GTK_BIN (widget)), snapshot);
+ gtk_container_snapshot_child (GTK_CONTAINER (widget), gtk_bin_get_child (GTK_BIN (widget)), snapshot);
for (l = priv->popovers; l; l = l->next)
{
GtkWindowPopover *data = l->data;
- gtk_container_snapshot_child (GTK_CONTAINER (widget), node, data->widget, snapshot);
+ gtk_container_snapshot_child (GTK_CONTAINER (widget), data->widget, snapshot);
}
- updates_node = gtk_debug_updates_snapshot (widget, snapshot);
- if (updates_node)
- {
- gsk_render_node_append_child (node, updates_node);
- gsk_render_node_unref (updates_node);
- }
+ gtk_debug_updates_snapshot (widget, snapshot);
- return node;
+ gtk_snapshot_pop (snapshot);
}
/**